package com.ideaaedi.springcloud.jd.commonspring.listener;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ideaaedi.commonds.time.DateTimeConverter;
import com.ideaaedi.commonspring.annotation.RecordParameters;
import com.ideaaedi.springcloud.jd.commonds.entity.BaseCodeMsgEnum;
import com.ideaaedi.springcloud.jd.commonds.his.HisIdentify;
import com.ideaaedi.springcloud.jd.commonds.event.NeedAddHisEvent;
import com.ideaaedi.springcloud.jd.commonds.event.NeedDeleteHisEvent;
import com.ideaaedi.springcloud.jd.commonds.exception.BaseException;
import com.ideaaedi.springcloud.jd.commonspring.mybatisplus.MybatisPlusInfoHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 历史数据相关事件监听器
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.5.B
 */
@Slf4j
@Component
@RecordParameters
public class HisListener {
    
    @Resource
    private MybatisPlusInfoHolder mybatisPlusInfoHolder;
    
    @EventListener
    @SuppressWarnings("unchecked")
    public void handleNeedAddHisEvent(NeedAddHisEvent event) {
        Class<? extends HisIdentify> hisEntityClazz = event.getHisClazz();
        List<?> poList = event.getPoList();
        IService<HisIdentify> hisService = (IService<HisIdentify>)mybatisPlusInfoHolder.getClazzServiceMapping().get(hisEntityClazz);
        Objects.requireNonNull(hisService, "hisService cannot be null. curr hisEntityClazz -> " + hisEntityClazz.getName());
        Constructor<? extends HisIdentify> hisEntityClazzConstructor = mybatisPlusInfoHolder.getClazzConstructorMapping().get(hisEntityClazz);
        Long now = Long.parseLong(DateTimeConverter.COMPACT_DATE_TIME.now());
        List<HisIdentify> hisPoList = poList.stream().map(x -> {
            HisIdentify hisPo;
            try {
                hisPo = hisEntityClazzConstructor.newInstance();
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                throw new BaseException("auto-create empty hisPo fail.", BaseCodeMsgEnum.FAILURE);
            }
            hisPo.setHisVersion(now);
            BeanUtils.copyProperties(x, hisPo);
            return hisPo;
        }).collect(Collectors.toList());
        hisService.saveBatch(hisPoList);
    }
    
    @EventListener
    public void handleNeedDeleteHisEvent(NeedDeleteHisEvent event) {
        Class<? extends HisIdentify> hisEntityClazz = event.getHisClazz();
        List<? extends Number> idList = event.getIdList();
        //noinspection unchecked
        IService<HisIdentify> hisService = (IService<HisIdentify>)mybatisPlusInfoHolder.getClazzServiceMapping().get(hisEntityClazz);
        QueryWrapper<HisIdentify> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(HisIdentify.BIZ_ID_PROPERTY_NAME, idList);
        hisService.remove(queryWrapper);
    }
}
